 /*******************************************************************************
  * Copyright (c) 2000, 2005 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.ui.internal.forms.widgets;

 import java.util.ArrayList ;

 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.widgets.Display;

 public class SelectionData {
     public Display display;
     public Color bg;
     public Color fg;
     private Point start;
     private Point stop;
     private ArrayList segments;
     private boolean newLineNeeded;
     
     public SelectionData(MouseEvent e) {
         display = e.display;
         segments = new ArrayList ();
         start = new Point(e.x, e.y);
         stop = new Point(e.x, e.y);
         bg = e.display.getSystemColor(SWT.COLOR_LIST_SELECTION);
         fg = e.display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
     }
     
     public void markNewLine() {
         newLineNeeded=true;
     }
     public void addSegment(String text) {
         if (newLineNeeded) {
             segments.add(System.getProperty("line.separator")); //$NON-NLS-1$
 newLineNeeded=false;
         }
         segments.add(text);
     }

     public void update(MouseEvent e) {
         //Control c = (Control)e.widget;
 stop.x = e.x;
         stop.y = e.y;
     }
     public void reset() {
         segments.clear();
     }
     public String getSelectionText() {
         StringBuffer buf = new StringBuffer ();
         for (int i=0; i<segments.size(); i++) {
             buf.append((String )segments.get(i));
         }
         return buf.toString();
     }
     public boolean canCopy() {
         return segments.size()>0;
     }
     
     private int getTopOffset() {
         return start.y<stop.y?start.y:stop.y;
     }
     private int getBottomOffset() {
         return start.y>stop.y?start.y:stop.y;
     }
     public int getLeftOffset(Locator locator) {
         return isInverted(locator)? stop.x:start.x;
     }
     public int getLeftOffset(int rowHeight) {
         return isInverted(rowHeight) ? stop.x:start.x;
     }
     public int getRightOffset(Locator locator) {
         return isInverted(locator)? start.x: stop.x;
     }
     public int getRightOffset(int rowHeight) {
         return isInverted(rowHeight) ? start.x:stop.x;
     }
     private boolean isInverted(Locator locator) {
         int rowHeight = ((int [])locator.heights.get(locator.rowCounter))[0];
         return isInverted(rowHeight);
     }
     private boolean isInverted(int rowHeight) {
         int deltaY = start.y - stop.y;
         if (Math.abs(deltaY) > rowHeight) {
             // inter-row selection
 return deltaY>0;
         }
         // intra-row selection
 return start.x > stop.x;
     }
     public boolean isEnclosed() {
         return !start.equals(stop);
     }

     public boolean isSelectedRow(Locator locator) {
         if (!isEnclosed())
             return false;
         int rowHeight = ((int [])locator.heights.get(locator.rowCounter))[0];
         return isSelectedRow(locator.y, rowHeight);
     }
     public boolean isSelectedRow(int y, int rowHeight) {
         if (!isEnclosed())
             return false;
         return (y + rowHeight >= getTopOffset() &&
                 y <= getBottomOffset());
     }
     public boolean isFirstSelectionRow(Locator locator) {
         if (!isEnclosed())
             return false;
         int rowHeight = ((int [])locator.heights.get(locator.rowCounter))[0];
         return (locator.y + rowHeight >= getTopOffset() &&
                 locator.y <= getTopOffset());
     }
     public boolean isFirstSelectionRow(int y, int rowHeight) {
         if (!isEnclosed())
             return false;
         return (y + rowHeight >= getTopOffset() &&
                 y <= getTopOffset());
     }
     public boolean isLastSelectionRow(Locator locator) {
         if (!isEnclosed())
             return false;
         int rowHeight = ((int [])locator.heights.get(locator.rowCounter))[0];
         return (locator.y + rowHeight >=getBottomOffset() &&
                 locator.y <= getBottomOffset());
     }
     public boolean isLastSelectionRow(int y, int rowHeight) {
         if (!isEnclosed())
             return false;
         return (y + rowHeight >=getBottomOffset() &&
                 y <= getBottomOffset());
     }
 }

